package health.carousel.parsers;

import health.carousel.data.HtmlSafeString;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.mail.MessagingException;
import javax.mail.Multipart;
import javax.mail.Part;
import java.io.IOException;

public class ContentParser {
    private static final Logger log = LoggerFactory.getLogger(ContentParser.class);

    public HtmlSafeString parseMessageContent(Object content) throws MessagingException, IOException {
        int letterLimit = 100;
        String text;
        boolean textIsHtml = false;
        if (content instanceof String) {
            text = (String) content;
            if(text.contains("<html")){
                textIsHtml = true;
            }
        } else if (content instanceof Part) {
            HtmlSafeString htmlSafeString = getTextFromPart((Part) content);
            text = htmlSafeString.getText();
            textIsHtml = htmlSafeString.isHtml();
        } else if (content instanceof Multipart) {
            HtmlSafeString htmlSafeString = getTextFromMultiPart((Multipart) content);
            text = htmlSafeString.getText();
            textIsHtml = htmlSafeString.isHtml();
        } else {
            text = "[UNKNOWN CONTENT], content type: " + content.getClass();
        }

        log.info("    Body of " + (textIsHtml ? "<HTML>" : "TEXT") + " format: " +
                (text.length() > letterLimit
                        ? text.substring(0, letterLimit) + ".......[_BODY_TOO_LONG_]"
                        : text));

        return new HtmlSafeString(text, textIsHtml);
    }


    private static HtmlSafeString getTextFromMultiPart(Multipart multipart) throws MessagingException, IOException {
        String text = null;
        boolean textIsHtml = false;

        for (int partNumber = 0; partNumber < multipart.getCount(); partNumber++) {
            Part bodyPart = multipart.getBodyPart(partNumber);
            if (bodyPart.isMimeType("text/plain")) {
                if (text == null) {
                    HtmlSafeString htmlSafeString = getTextFromPart(bodyPart);
                    text = htmlSafeString.getText();
                    textIsHtml = htmlSafeString.isHtml();
                }
            } else if (bodyPart.isMimeType("text/html")) {
                HtmlSafeString s = getTextFromPart(bodyPart);
                if (s.getText() != null) {
                    return s;
                }
            } else {
                if(text == null){
                    return getTextFromPart(bodyPart);
                }
            }
        }

        return new HtmlSafeString(text, textIsHtml);
    }

    private static HtmlSafeString getTextFromPart(Part part) throws MessagingException, IOException {
        if (part.isMimeType("text/*")) {
            String text = (String) part.getContent();
            boolean textIsHtml = part.isMimeType("text/html");

            return new HtmlSafeString(text, textIsHtml);
        }

        if (part.isMimeType("multipart/alternative")) {
            Multipart multipart = (Multipart) part.getContent();
            String text = null;
            boolean textIsHtml = false;
            for (int partNumber = 0; partNumber < multipart.getCount(); partNumber++) {
                Part bodyPart = multipart.getBodyPart(partNumber);
                if (bodyPart.isMimeType("text/plain")) {
                    if (text == null) {
                        HtmlSafeString htmlSafeString = getTextFromPart(bodyPart);
                        text = htmlSafeString.getText();
                        textIsHtml = htmlSafeString.isHtml();
                    }
                } else if (bodyPart.isMimeType("text/html")) {
                    HtmlSafeString s = getTextFromPart(bodyPart);
                    if (s.getText() != null)
                        return s;
                } else {
                    return getTextFromPart(bodyPart);
                }
            }

            return new HtmlSafeString(text, textIsHtml);

        } else if (part.isMimeType("multipart/*")) {
            Multipart multipart = (Multipart) part.getContent();
            for (int partNumber = 0; partNumber < multipart.getCount(); partNumber++) {
                HtmlSafeString s = getTextFromPart(multipart.getBodyPart(partNumber));
                if (s.getText() != null) {
                    return s;
                }
            }
        }

        return new HtmlSafeString(null, false);
    }
}
